﻿using System;
using System.Data;
using System.Configuration;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using System.Data.SqlClient;
using System.IO;
using System.Text;
using System.Diagnostics;
using System.Xml;
using System.Xml.XPath;
using System.Xml.Serialization;
using System.Globalization;
namespace QA_System
{
    public class STRINGCLASS
    {
        static private string vnTagger = QA_System.Properties.Settings.Default.vnTaggerAbsolutePath;
        static private string xmlDatabasePath = QA_System.Properties.Settings.Default.xmlDatabasePath;
        // thay tu bi phan tich sai thanh tu thay the, them dau cau.
        public static string fixword(string asktext)
        {

            string word1 = "bức tranh";
            string word2 = "Bức tranh";
            string word4 = "giá tiền";
            string word3 = "giá cả";
            asktext = asktext.Replace("?", "?>");
            asktext = asktext.Replace(".", ".>");
          
            if (asktext.IndexOf(word1) != -1) asktext = asktext.Replace(word1, "tranh");
            if (asktext.IndexOf(word2) != -1) asktext = asktext.Replace(word2, "tranh");
            if (asktext.IndexOf(word3) != -1) asktext = asktext.Replace(word3, "giá");
            if (asktext.IndexOf(word4) != -1) asktext = asktext.Replace(word4, "giá");

            return asktext;

        }

        // ghi cau hoi tu textbox ra file text de chuan bi cho viec tagger.
        // luu moi cau 1 dong moi cho phan tich dung
        public static void getSentences(string asktext, string outputFile)
        {
            using (StreamWriter output = new StreamWriter(outputFile))
            {
                string[] _sentence = asktext.Split('>');
                int i = 0;

                while (i < _sentence.Length)
                {
                    byte[] utf8String = Encoding.UTF8.GetBytes(_sentence[i]);
                    output.WriteLine(Encoding.UTF8.GetString(utf8String));
                    i = i + 1;
                    output.Flush();
                }

                output.Close();
            }
        }


        //tien hanh tagger file cau hoi da luu
        public static void tagger(string inputFile, string outputFile)
        {
            Process process = new Process();
            process.StartInfo.UseShellExecute = true;
            process.StartInfo.RedirectStandardOutput = false;
            process.StartInfo.RedirectStandardError = false;
            process.StartInfo.FileName = "cmd.exe";
            process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
            //process.StartInfo.CreateNoWindow = false;
            process.StartInfo.Arguments = "/c "+ vnTagger +" -i "+ inputFile+ " -o " + outputFile;
            process.Start();
            process.WaitForExit();
            process.Close();
        }

        // goi bkparser
        public static void bkparser()
        {
            Process process = new Process();
            process.StartInfo.UseShellExecute = true;
            process.StartInfo.RedirectStandardOutput = false;
            process.StartInfo.RedirectStandardError = false;
            process.StartInfo.FileName = "cmd.exe";
            //process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
            //process.StartInfo.CreateNoWindow = false;
            process.StartInfo.WorkingDirectory = "C:\\bkparser_desktop";
            //process.StartInfo.Arguments = "/c C:\\bkparser_desktop\\connect.bat";
            process.StartInfo.Arguments = "/c java -Dinput=text1.txt -Doutput=text1.xml -jar BKParser.jar";
            // text1.txt và text1.xml là file đầu vào nằm trong thư mục C:\\bkparser_desktop
            process.Start();
            process.WaitForExit();
            process.Close();

        }

        // doc file sau khi tagger
        public static List<sentence_tagger> readXmlFile2(string istrPath)
        {
            XmlDocument newdoc = new XmlDocument();
            newdoc.Load(istrPath);
            XmlNodeList nodelist = newdoc.SelectNodes("//s");
            int l = nodelist.Count;
            List<sentence_tagger> sentenceList = new List<sentence_tagger>(l);// so cau            
            foreach (XmlNode node in nodelist)
            {
                int j = 0;
                sentence_tagger sentence;
                sentence = new sentence_tagger(node.ChildNodes.Count);
                foreach (XmlNode child in node.ChildNodes)
                {
                    sentence[j].Word_pos = child.Attributes["pos"].Value;
                    sentence[j].Word_text = child.InnerText;
                    j++;
                }
                sentenceList.Add(PrepareStructure.FixSentence(sentence));                
            }
            return sentenceList;
        }
        public static sentence_tagger[] readXmlFile1(string istrPath)
        {
            XmlDocument newdoc = new XmlDocument();
            newdoc.Load(istrPath);
            XmlNodeList nodelist = newdoc.SelectNodes("//s");
            int l = nodelist.Count;

            sentence_tagger[] sentencelistmember = new sentence_tagger[l];// so cau

            int i = 0;


            foreach (XmlNode node in nodelist)
            {
                int j = 0;
                sentence_tagger sentencelist;
                sentencelist= new sentence_tagger(node.ChildNodes.Count);
                foreach (XmlNode child in node.ChildNodes)
                {
                    sentencelist[j].Word_pos = child.Attributes["pos"].Value;
                    sentencelist[j].Word_text = child.InnerText;
                    j++;

                }
                sentencelistmember[i] = sentencelist;
                i++;
            }
            return sentencelistmember;

        }

        public static sentence_tagger[] readXmlFile(string istrPath)
        {
            try
            {
                XmlDocument newdoc = new XmlDocument();
                newdoc.Load(istrPath);
                XmlNodeList nodelist = newdoc.SelectNodes("//s");
                if (nodelist != null)
                {
                    sentence_tagger finalSentence;
                    sentence_tagger[] sentencelistmember = new sentence_tagger[nodelist.Count];// so cau
                    sentence_tagger sentencelist;
                    int i = 0;
                    #region sentence optimiz
                    foreach (XmlNode node in nodelist)
                    {
                        int j = 0;
                        sentencelist = new sentence_tagger(node.ChildNodes.Count);
                        foreach (XmlNode child in node.ChildNodes)
                        {
                            if (child.InnerText.ToLower().Equals("bao nhieu"))
                            {
                                sentencelist[j].Word_pos = "X";
                                sentencelist[j].Word_text = child.InnerText;
                                j++;
                            }
                            else
                            {

                                if (j > 0)
                                {
                                    #region j>0
                                    if ((sentencelist[j - 1].Word_pos.Contains("N")) && (child.Attributes["pos"].Value.Contains("N")))
                                    {
                                        if (sentencelist[j - 1].Word_pos.Equals("Nc"))
                                        {
                                            sentencelist[j - 1].Word_text += " " + child.InnerText;
                                            sentencelist[j - 1].Word_pos = child.Attributes["pos"].Value;
                                        }
                                        else
                                        {

                                            string strWord = sentencelist[j - 1].Word_text + " " + child.InnerText;
                                            if (XMLNounConnection.IsCompositNoun(strWord, xmlDatabasePath + "NounXMLdatabase.xml"))
                                            {
                                                sentencelist[j - 1].Word_text = strWord;
                                            }
                                            else
                                            {
                                                sentencelist[j].Word_pos = child.Attributes["pos"].Value;
                                                sentencelist[j].Word_text = child.InnerText;
                                                j++;
                                            }
                                        }
                                    }
                                    else
                                    {
                                        if ((sentencelist[j - 1].Word_pos.Equals("P")) && (child.Attributes["pos"].Value.Equals("P")))
                                        {
                                            sentencelist[j - 1].Word_pos = "XX";
                                            sentencelist[j].Word_pos = "XX";
                                            sentencelist[j].Word_text = child.InnerText;
                                            j++;
                                        }
                                        else
                                        {
                                            if ((sentencelist[j - 1].Word_pos.Equals("V")) && (child.Attributes["pos"].Value.Equals("V")))
                                            {
                                                sentencelist[j - 1].Word_text += " " + child.InnerText;
                                            }
                                            else
                                            {
                                                if (child.InnerText != string.Empty)
                                                {
                                                    sentencelist[j].Word_pos = child.Attributes["pos"].Value;
                                                    sentencelist[j].Word_text = child.InnerText;
                                                    j++;
                                                }
                                            }
                                        }
                                    }
                                    #endregion
                                }
                                else
                                {
                                    if ((!string.IsNullOrEmpty(child.InnerText)) || (child.InnerText != " "))
                                    {
                                        sentencelist[j].Word_pos = child.Attributes["pos"].Value;
                                        sentencelist[j].Word_text = child.InnerText;
                                        j++;
                                    }
                                }
                            }
                        }
                        #region intinize...
                        finalSentence = new sentence_tagger(j);
                        for (int k = 0; k < j; k++) finalSentence[k] = sentencelist[k];
                        #endregion
                        sentencelistmember[i] = finalSentence;
                        i++;
                    }
                    #endregion
                    return sentencelistmember;
                }
                else return null;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        // tim tu khoa la so tu
        public static string extract_keyword_M(sentence_tagger keyword)
        {
            string keyword_true = "";
            int total = keyword.totalword();
            for (int i = 2; i < total; i++)
                if (keyword[i].Word_pos == "M")
                    keyword_true += keyword[i].Word_text.ToString() ; 
                    //keyword_true += keyword[i].Word_text + " ";

            return keyword_true;
        }

        // tim tu khoa la tu chi truong phai hay chat lieu
        public static string extract_keyword_G_M(sentence_tagger keyword)
        {
            string keyword_true = "";
            string all_g_m = Genre.GetAllKindOfGenre() + Painting.GetAllMaterial();
            int total = keyword.totalword();
            string keyword_string = "";
            for (int j = 2; j < total; j++) keyword_string += keyword[j].Word_text + " ";
            string[] all_g_m_list = all_g_m.Split('/');
            bool stop = false; int i = 0;
            while (stop == false)
            {
                if (keyword_string.Contains(all_g_m_list[i])) { keyword_true = all_g_m_list[i]; stop = true; }
                else { i++; if (i == all_g_m_list.Length) stop = true; }
            }
            return keyword_true;
        }

        // tim tu khoa la danh tu rieng
        public static string extract_keyword_N(sentence_tagger keyword)
        {
            string keyword_true = "";
            string keyword_true_rev = "";
            int total = keyword.totalword();
            string keyword_string = "";
            for (int j = 2; j < total; j++) keyword_string += keyword[j].Word_text + " ";

            string[] keyword_string_array = keyword_string.Split(' ');
            bool stop = false; int i = keyword_string_array.Length - 2;


            // tim nguoc xau
            while (stop == false)
            {
                char[] charArr = keyword_string_array[i].ToCharArray();
                if ((charArr[0].ToString() == charArr[0].ToString().ToUpper()) && (!Char.IsDigit(charArr[0])))
                {
                    if (i == 0)
                    {
                        if (keyword_true != "")
                        {
                            if ((keyword_string_array[i] != "Tranh") && (keyword_string_array[i] != "Bức"))
                                keyword_true += keyword_string_array[i] + " ";
                        }
                        stop = true;
                    }
                    else
                    {
                        keyword_true += keyword_string_array[i] + " ";
                        i--;

                    }
                }
                else
                {
                    if (keyword_true == "")
                    {
                        i--;
                        if (i == -1) stop = true;
                    }
                    else
                    { stop = true; }

                }
            }

            // dao lai xau
            string[] keyword_true_array = keyword_true.Split(' ');
            for (int k = (keyword_true_array.Length - 2); k >= 0; k--)
            {
                if (k != 0) keyword_true_rev += keyword_true_array[k] + " ";
                else keyword_true_rev += keyword_true_array[k];
            }


            return keyword_true_rev;
        }

        // lay cac nut con, danh dau de dua vao hang doi
        public static void get_node_wait_list(ref XmlNode currentnode, int last_word_macth, ref nodewaitlist node_wait_list)
        {
            XmlNodeList nodelist = currentnode.ChildNodes;
            // chuyen currentnode thanh nut con dau tien khac * tim dc
            int i = 0; bool change = false;
            while (change == false)
            {
                if (nodelist[i].Attributes["name"].Value.ToString() != "*")
                {
                    currentnode = nodelist[i];
                    change = true;
                }
                else { i++; }
            }

            //đua cac nut  * vao 

            for (int j = 0; j < nodelist.Count; j++)
            {
                if (nodelist[j].Attributes["name"].Value.ToString() == "*")
                    node_wait_list[node_wait_list.total_element()].set_node(nodelist[j], last_word_macth);
            }


            //đua cac nut khac * vao 
            for (int j = (nodelist.Count - 1); j >= 0; j--)
            {
                if ((nodelist[j].Attributes["name"].Value.ToString() != "*") && (j != i))
                    node_wait_list[node_wait_list.total_element()].set_node(nodelist[j], last_word_macth);
            }

        }

        // kiem tra xem nut XML co chua tu khong?
        public static bool is_content(string root_string, string word_compare)
        {
            string[] root_mem = root_string.Split('/');
            bool content = false;
            int i = 0;
            while ((content == false) && (i < root_mem.Length))
            {
                if (root_mem[i].Equals(word_compare.ToLower())) content = true;
                i++;
            }
            return content;
        }

        // lay toan bo duong di cua Token tim duoc, nguoc tu nut cuoi (EAT)
        public static string get_path_node(XmlNode node)
        {
            string path = node.Attributes["id"].Value.ToString() + " ";
            while (node.ParentNode.Name != "begin")
            {
                path += node.ParentNode.Attributes["id"].Value.ToString() + " ";
                node = node.ParentNode;

            }
            return path;

        }

        
        // duyet cau hoi, tim ra EAT 
        public static string loadXmlTrie(string istrPath, sentence_tagger sentence, ref string[] keyword_list)
        {
            XmlDocument newdoc = new XmlDocument();
            newdoc.Load(istrPath);
            XmlNodeList nodelist1 = newdoc.SelectNodes("//begin");
            XmlNode currentnode = nodelist1[0];


            int total_Word = sentence.totalword() - 1;
            int word_count = 0;
            int keyword_count = 0;
            int last_word_macth = 0;
            sentence_tagger[] Key_Word = new sentence_tagger[20];
            string[] path_trie_list = new string[8];// cac token tim duoc
            string[] EAT = new string[4];// cac EAT tương ưng voi cac token
            int path_trie_count = 0;

            nodewaitlist node_wait_list = new nodewaitlist(); // danh sach cac nut doi xet


            get_node_wait_list(ref currentnode, last_word_macth, ref node_wait_list);
            
            int test = 0;// 1 tim ra EAT, 0 dang xet, -1 ko tim dc

            string keytest = "";
            while (test == 0)
            {
                keytest += currentnode.Attributes["id"].Value + ";" + sentence[word_count].Word_text + ";" + word_count.ToString() + "__";// de xem xet qua trinh duyet
                // neu currentnode khac *
                if (currentnode.Attributes["name"].Value.ToString() != "*")
                {
                    //loi  phai so sanh 
                    if (is_content(currentnode.Attributes["name"].Value, sentence[word_count].Word_text.ToLower()))
                    {

                        if (currentnode.ParentNode.Name != "begin")
                            if (currentnode.ParentNode.Attributes["name"].Value.ToString() == "*")
                            {
                                sentence_tagger temp = new sentence_tagger();
                                temp[0].Word_text = currentnode.ParentNode.Attributes["id"].Value.ToString();
                                temp[0].Word_pos = "index";
                                temp[1].Word_text = currentnode.Attributes["id"].Value.ToString();
                                temp[1].Word_pos = "index";
                                int temp_count = 2;

                                for (int k = last_word_macth; k < word_count; k++)
                                {
                                    temp[temp_count].Word_text = sentence[k].Word_text;
                                    temp[temp_count].Word_pos = sentence[k].Word_pos;
                                    temp_count++;
                                }
                                Key_Word[keyword_count] = temp;
                                keyword_count++;
                            }

                        last_word_macth = word_count;

                        if (word_count == total_Word)//if (last_word_macth == total_Word)
                        {
                            if (currentnode.Attributes["name"].Value.ToString() == "?") // neu la nut cuoi trong trie
                            {
                                test = 1;// tu xet la tu cuoi cung => tim dc EAT
                                path_trie_list[path_trie_count] = get_path_node(currentnode);// luu nhanh vua tim duoc
                                EAT[path_trie_count] = currentnode.Attributes["EAT"].Value;// luu EAT tim duoc
                                path_trie_count++;
                                if (node_wait_list.total_element() != 0)
                                {
                                    test = 0;
                                    currentnode = node_wait_list[(node_wait_list.total_element() - 1)].node_content();
                                    word_count = node_wait_list[(node_wait_list.total_element() - 1)].mark_word();
                                    last_word_macth = word_count;
                                    node_wait_list[(node_wait_list.total_element() - 1)].set_mark_work();
                                }
                            }
                            else
                            {
                                if (node_wait_list.total_element() == 0) test = -1;
                                else
                                {
                                    currentnode = node_wait_list[(node_wait_list.total_element() - 1)].node_content();
                                    word_count = node_wait_list[(node_wait_list.total_element() - 1)].mark_word();
                                    last_word_macth = word_count;
                                    node_wait_list[(node_wait_list.total_element() - 1)].set_mark_work();
                                }
                            }
                        }
                        else
                        {
                            if (currentnode.Attributes["name"].Value.ToString() == "?")
                            {
                                if (node_wait_list.total_element() == 0) test = -1;
                                else
                                {
                                    currentnode = node_wait_list[(node_wait_list.total_element() - 1)].node_content();
                                    word_count = node_wait_list[(node_wait_list.total_element() - 1)].mark_word();
                                    last_word_macth = word_count;
                                    node_wait_list[(node_wait_list.total_element() - 1)].set_mark_work();
                                }
                            }
                            else
                            {
                                if (currentnode.ChildNodes.Count == 1) currentnode = currentnode.FirstChild;
                                if (currentnode.ChildNodes.Count > 1) get_node_wait_list(ref currentnode, last_word_macth+1, ref node_wait_list);
                                word_count++;

                            }
                        }

                    }
                    else
                    {
                        if (word_count == total_Word)
                        {
                            if (node_wait_list.total_element() == 0) test = -1;
                            else
                            {
                                currentnode = node_wait_list[(node_wait_list.total_element() - 1)].node_content();
                                word_count = node_wait_list[(node_wait_list.total_element() - 1)].mark_word();
                                last_word_macth = word_count;
                                node_wait_list[(node_wait_list.total_element() - 1)].set_mark_work();
                            }
                        }
                        else
                        {
                            word_count++;
                        }

                    }

                }


                // neu currentnode la *
                else
                {
                    if (word_count == total_Word)
                    {
                        if (node_wait_list.total_element() == 0) test = -1;
                        else
                        {
                            currentnode = node_wait_list[(node_wait_list.total_element() - 1)].node_content();
                            word_count = node_wait_list[(node_wait_list.total_element() - 1)].mark_word();
                            last_word_macth = word_count;
                            node_wait_list[(node_wait_list.total_element() - 1)].set_mark_work();
                        }

                    }
                    else
                    {
                        //if (currentnode.ChildNodes.Count == 1) currentnode = currentnode.FirstChild;
                        //if (currentnode.ChildNodes.Count > 1) get_node_wait_list(ref currentnode, word_count, ref node_wait_list);
                        get_node_wait_list(ref currentnode, word_count, ref node_wait_list);
                        last_word_macth = word_count;
                        word_count++;
                    }

                }

            }


            //Neu tim duoc nhieu nhanh phu hop thi chon nhanh co nhieu nut nhat

            int path_length = 0;
            string path_true = "";
            string EAT_true = "";

            for (int m = 0; m < 8; m++)
            {
                if (path_trie_list[m] != null)
                {

                    string[] temp_path_array = path_trie_list[m].Split(' ');
                    if (path_length < temp_path_array.Length)
                    {
                        path_true = path_trie_list[m];
                        EAT_true = EAT[m];
                        path_length = temp_path_array.Length;
                    }


                }
            }

            sentence_tagger[] Key_Word_true = new sentence_tagger[7];
            int Key_Word_true_count = 0;

            // lay danh sach tu khoa thuc su
            if (EAT_true == "") { return ("Exception: hệ thống không hiểu câu hỏi."); }
            else
            {

                string[] path_mem = path_true.Split(' ');

                for (int k = 0; k < keyword_count; k++)
                {
                    sentence_tagger keyword_temp = Key_Word[k];
                    for (int i = 0; i < path_mem.Length; i++)
                    {
                        if (path_mem[i] == keyword_temp[0].Word_text)
                        {
                            for (int j = 0; j < path_mem.Length; j++)
                                if (path_mem[j] == keyword_temp[1].Word_text)
                                {
                                    Key_Word_true[Key_Word_true_count] = Key_Word[k];
                                    Key_Word_true_count++;
                                }
                        }
                    }
                }

                // trich xuat tu khoa
               
                for (int p = 0; p < Key_Word_true_count; p++)
                {
                    string keyword_N = STRINGCLASS.extract_keyword_N(Key_Word_true[p]);
                    if (keyword_N != "") keyword_list[p] = keyword_N;
                    else
                    {
                        string keyword_G_M = STRINGCLASS.extract_keyword_G_M(Key_Word_true[p]);
                        if (keyword_G_M != "") keyword_list[p] = keyword_G_M;
                        else
                        { 
                            string keyword_M = STRINGCLASS.extract_keyword_M(Key_Word_true[p]);
                            if (keyword_M != "") keyword_list[p] = keyword_M;
                            else 
                            {
                                sentence_tagger sentence_temp = Key_Word_true[p];
                                int total_word1 = sentence_temp.totalword();
                                for (int i = 2; i < total_word1; i++)
                                {
                                    if (i == (total_word1 - 1)) keyword_list[p] += sentence_temp[i].Word_text;
                                   else keyword_list[p] += sentence_temp[i].Word_text + " "; 
                                }
                            }
                        }
                    }
                
                }

                string temp = EAT_true.ToString() + "@" + path_true.ToString();
                return temp;
                //return EAT_true;

            }          

            



        }

       


        
    }
}
